// **************************************************************
// COPYRIGHT(c)2016, Xidian University
// All rights reserved.
//
// IP LIB INDEX :  
// IP Name      :      
// File name    :  
// Module name  :  
// Full name    :  
// Time         : 2016 
// Author       : Wang-Weina 
// Email        : 327422289@qq.com
// Data         : 
// Version      : V 1.0 
// 
// Abstract     :
// Called by    :  
// 
// Modification history
// -----------------------------------------------------------------
// 
// 
//
// *****************************************************************

// *******************
// TIMESCALE
// ******************* 
`timescale 1ns/1ps 

// *******************
// INFORMATION
// *******************

//*******************
//DEFINE(s)
//*******************
//`define UDLY 1    //Unit delay, for non-blocking assignments in sequential logic

//*******************
//DEFINE MODULE PORT
//*******************
module  rbve_line_last#(
    parameter SUBR = 16,
    parameter RULE_SUM= 32,
    parameter LOG2R   = 5 ,
    parameter RANGE_L = 256
    )
   (
    input wire clk,
    input wire rst_n,
    input wire [11:0]ram_dp_cfg_register,
    input wire lookup_en,//\u4e00\u4e2a\u5468\u671f\u5c31\u53ef\u4ee5\u4e86
    input wire en_in,
    input wire odd,
    input wire[7:0] addr_loc,// 2022.5.9, xym
    // input wire[8:0] addr_loc,
    input wire mod_en,
    input wire[95:0] cpu_data,
    output wire[95:0] cpu_data_o,
    output reg lookup_done,
    input wire[0:RULE_SUM-1] match_in,
    input wire[RANGE_L-1:0] range,
    // output reg[RANGE_L-1-SUBR:0] range_out,//\u6700\u540e\u4e00\u7ea7\u65e0\u540e\u7eed\u5b57\u6bb5\u8f93\u51fa
    output wire[0:RULE_SUM-1] match_out,
    output wire match_is
    );

//*******************
//DEFINE LOCAL PARAMETER
//*******************
//parameter(s)

             
                                    

 

//*********************
//INNER SIGNAL DECLARATION
//*********************
//REGS
wire match_r0,match_r1,match_r2,match_r3,match_r4,match_r5,match_r6,match_r7,match_r8,match_r9,
    match_r10,match_r11,match_r12,match_r13,match_r14,match_r15,match_r16,match_r17,match_r18,match_r19,
    match_r20,match_r21,match_r22,match_r23,match_r24,match_r25,match_r26,match_r27,match_r28,match_r29,
    match_r30,match_r31;
reg lookup_en_ff1,lookup_en_ff2,lookup_en_ff3;
// reg[RANGE_L-1-SUBR:0] range_ff1,range_ff2;
reg[0:RULE_SUM-1] match_in_ff1,match_in_ff2,match_in_ff3,match_in_ff4;
reg mod_en1,mod_en2;
reg[7:0] addr_loc1;
reg[7:0] addr_loc2;
reg[95:0] cpu_data1;
reg[63:0] cpu_data2;
//WIRES
wire[95:0] cpu_data_o1;
wire[63:0] cpu_data_o2;

assign cpu_data_o = (odd)?{32'h0,cpu_data_o2}:cpu_data_o1;
wire[2:0]  rbve_out1_r0 ;
wire[2:0]  rbve_out1_r1 ;
wire[2:0]  rbve_out1_r2 ;
wire[2:0]  rbve_out1_r3 ;
wire[2:0]  rbve_out1_r4 ;
wire[2:0]  rbve_out1_r5 ;
wire[2:0]  rbve_out1_r6 ;
wire[2:0]  rbve_out1_r7 ;
wire[2:0]  rbve_out1_r8 ;
wire[2:0]  rbve_out1_r9 ;
wire[2:0]  rbve_out1_r10;
wire[2:0]  rbve_out1_r11;
wire[2:0]  rbve_out1_r12;
wire[2:0]  rbve_out1_r13;
wire[2:0]  rbve_out1_r14;
wire[2:0]  rbve_out1_r15;
wire[2:0]  rbve_out1_r16;
wire[2:0]  rbve_out1_r17;
wire[2:0]  rbve_out1_r18;
wire[2:0]  rbve_out1_r19;
wire[2:0]  rbve_out1_r20;
wire[2:0]  rbve_out1_r21;
wire[2:0]  rbve_out1_r22;
wire[2:0]  rbve_out1_r23;
wire[2:0]  rbve_out1_r24;
wire[2:0]  rbve_out1_r25;
wire[2:0]  rbve_out1_r26;
wire[2:0]  rbve_out1_r27;
wire[2:0]  rbve_out1_r28;
wire[2:0]  rbve_out1_r29;
wire[2:0]  rbve_out1_r30;
wire[2:0]  rbve_out1_r31;

wire[1:0]  rbve_out2_r0 ;
wire[1:0]  rbve_out2_r1 ;
wire[1:0]  rbve_out2_r2 ;
wire[1:0]  rbve_out2_r3 ;
wire[1:0]  rbve_out2_r4 ;
wire[1:0]  rbve_out2_r5 ;
wire[1:0]  rbve_out2_r6 ;
wire[1:0]  rbve_out2_r7 ;
wire[1:0]  rbve_out2_r8 ;
wire[1:0]  rbve_out2_r9 ;
wire[1:0]  rbve_out2_r10;
wire[1:0]  rbve_out2_r11;
wire[1:0]  rbve_out2_r12;
wire[1:0]  rbve_out2_r13;
wire[1:0]  rbve_out2_r14;
wire[1:0]  rbve_out2_r15;
wire[1:0]  rbve_out2_r16;
wire[1:0]  rbve_out2_r17;
wire[1:0]  rbve_out2_r18;
wire[1:0]  rbve_out2_r19;
wire[1:0]  rbve_out2_r20;
wire[1:0]  rbve_out2_r21;
wire[1:0]  rbve_out2_r22;
wire[1:0]  rbve_out2_r23;
wire[1:0]  rbve_out2_r24;
wire[1:0]  rbve_out2_r25;
wire[1:0]  rbve_out2_r26;
wire[1:0]  rbve_out2_r27;
wire[1:0]  rbve_out2_r28;
wire[1:0]  rbve_out2_r29;
wire[1:0]  rbve_out2_r30;
wire[1:0]  rbve_out2_r31;

wire[7:0] range_first;
wire[7:0] range_second;
//*********************
//INSTANTCE MODULE
//*********************
rbve_1 U_1(
    .clk(clk),
    .rst_n(rst_n),
    .ram_dp_cfg_register(ram_dp_cfg_register),
    .lookup_en(en_in),
    .mod_en(mod_en1),
    .addr_loc(addr_loc1),
    .cpu_data(cpu_data1),
    .cpu_data_o_ff(cpu_data_o1),
    // .cpu_en_modify(cpu_en_modify),
    // .din_cpu(din_cpu),
    // .rule_loc(rule_loc),
    .range_first (range_first),
    .rbve_out_r0 (rbve_out1_r0 ),
    .rbve_out_r1 (rbve_out1_r1 ),
    .rbve_out_r2 (rbve_out1_r2 ),
    .rbve_out_r3 (rbve_out1_r3 ),
    .rbve_out_r4 (rbve_out1_r4 ),
    .rbve_out_r5 (rbve_out1_r5 ),
    .rbve_out_r6 (rbve_out1_r6 ),
    .rbve_out_r7 (rbve_out1_r7 ),
    .rbve_out_r8 (rbve_out1_r8 ),
    .rbve_out_r9 (rbve_out1_r9 ),
    .rbve_out_r10(rbve_out1_r10),
    .rbve_out_r11(rbve_out1_r11),
    .rbve_out_r12(rbve_out1_r12),
    .rbve_out_r13(rbve_out1_r13),
    .rbve_out_r14(rbve_out1_r14),
    .rbve_out_r15(rbve_out1_r15),
    .rbve_out_r16(rbve_out1_r16),
    .rbve_out_r17(rbve_out1_r17),
    .rbve_out_r18(rbve_out1_r18),
    .rbve_out_r19(rbve_out1_r19),
    .rbve_out_r20(rbve_out1_r20),
    .rbve_out_r21(rbve_out1_r21),
    .rbve_out_r22(rbve_out1_r22),
    .rbve_out_r23(rbve_out1_r23),
    .rbve_out_r24(rbve_out1_r24),
    .rbve_out_r25(rbve_out1_r25),
    .rbve_out_r26(rbve_out1_r26),
    .rbve_out_r27(rbve_out1_r27),
    .rbve_out_r28(rbve_out1_r28),
    .rbve_out_r29(rbve_out1_r29),
    .rbve_out_r30(rbve_out1_r30),
    .rbve_out_r31(rbve_out1_r31)
    );
rbve_2 U_2(
    .clk(clk),
    .rst_n(rst_n),
    .ram_dp_cfg_register(ram_dp_cfg_register),
    .lookup_en(en_in),
    .mod_en(mod_en2),
    .addr_loc(addr_loc2),
    .cpu_data(cpu_data2),
    .cpu_data_o_ff(cpu_data_o2),
    // .cpu_en_modify(cpu_en_modify),
    // .din_cpu(din_cpu),
    // .rule_loc(rule_loc),
    .range_second(range_second),
    .rbve_out_r0 (rbve_out2_r0 ),
    .rbve_out_r1 (rbve_out2_r1 ),
    .rbve_out_r2 (rbve_out2_r2 ),
    .rbve_out_r3 (rbve_out2_r3 ),
    .rbve_out_r4 (rbve_out2_r4 ),
    .rbve_out_r5 (rbve_out2_r5 ),
    .rbve_out_r6 (rbve_out2_r6 ),
    .rbve_out_r7 (rbve_out2_r7 ),
    .rbve_out_r8 (rbve_out2_r8 ),
    .rbve_out_r9 (rbve_out2_r9 ),
    .rbve_out_r10(rbve_out2_r10),
    .rbve_out_r11(rbve_out2_r11),
    .rbve_out_r12(rbve_out2_r12),
    .rbve_out_r13(rbve_out2_r13),
    .rbve_out_r14(rbve_out2_r14),
    .rbve_out_r15(rbve_out2_r15),
    .rbve_out_r16(rbve_out2_r16),
    .rbve_out_r17(rbve_out2_r17),
    .rbve_out_r18(rbve_out2_r18),
    .rbve_out_r19(rbve_out2_r19),
    .rbve_out_r20(rbve_out2_r20),
    .rbve_out_r21(rbve_out2_r21),
    .rbve_out_r22(rbve_out2_r22),
    .rbve_out_r23(rbve_out2_r23),
    .rbve_out_r24(rbve_out2_r24),
    .rbve_out_r25(rbve_out2_r25),
    .rbve_out_r26(rbve_out2_r26),
    .rbve_out_r27(rbve_out2_r27),
    .rbve_out_r28(rbve_out2_r28),
    .rbve_out_r29(rbve_out2_r29),
    .rbve_out_r30(rbve_out2_r30),
    .rbve_out_r31(rbve_out2_r31)
    );
LUT_5to1 U_r0(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r0),
    .second_2(rbve_out2_r0),
    .match(match_r0)
    );
LUT_5to1 U_r1(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r1),
    .second_2(rbve_out2_r1),
    .match(match_r1)
    );
LUT_5to1 U_l2(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r2),
    .second_2(rbve_out2_r2),
    .match(match_r2)
    );
LUT_5to1 U_l3(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r3),
    .second_2(rbve_out2_r3),
    .match(match_r3)
    );
LUT_5to1 U_r4(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r4),
    .second_2(rbve_out2_r4),
    .match(match_r4)
    );
LUT_5to1 U_r5(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r5),
    .second_2(rbve_out2_r5),
    .match(match_r5)
    );
LUT_5to1 U_r6(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r6),
    .second_2(rbve_out2_r6),
    .match(match_r6)
    );
LUT_5to1 U_r7(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r7),
    .second_2(rbve_out2_r7),
    .match(match_r7)
    );
LUT_5to1 U_r8(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r8),
    .second_2(rbve_out2_r8),
    .match(match_r8)
    );
LUT_5to1 U_r9(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r9),
    .second_2(rbve_out2_r9),
    .match(match_r9)
    );
LUT_5to1 U_r10(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r10),
    .second_2(rbve_out2_r10),
    .match(match_r10)
    );
LUT_5to1 U_r11(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r11),
    .second_2(rbve_out2_r11),
    .match(match_r11)
    );
LUT_5to1 U_r12(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r12),
    .second_2(rbve_out2_r12),
    .match(match_r12)
    );
LUT_5to1 U_r13(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r13),
    .second_2(rbve_out2_r13),
    .match(match_r13)
    );
LUT_5to1 U_r14(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r14),
    .second_2(rbve_out2_r14),
    .match(match_r14)
    );
LUT_5to1 U_r15(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r15),
    .second_2(rbve_out2_r15),
    .match(match_r15)
    );
LUT_5to1 U_r16(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r16),
    .second_2(rbve_out2_r16),
    .match(match_r16)
    );
LUT_5to1 U_r17(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r17),
    .second_2(rbve_out2_r17),
    .match(match_r17)
    );
LUT_5to1 U_r18(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r18),
    .second_2(rbve_out2_r18),
    .match(match_r18)
    );

LUT_5to1 U_r19(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r19),
    .second_2(rbve_out2_r19),
    .match(match_r19)
    );
LUT_5to1 U_r20(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r20),
    .second_2(rbve_out2_r20),
    .match(match_r20)
    );
LUT_5to1 U_r21(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r21),
    .second_2(rbve_out2_r21),
    .match(match_r21)
    );
LUT_5to1 U_r22(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r22),
    .second_2(rbve_out2_r22),
    .match(match_r22)
    );
LUT_5to1 U_r23(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r23),
    .second_2(rbve_out2_r23),
    .match(match_r23)
    );
LUT_5to1 U_r24(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r24),
    .second_2(rbve_out2_r24),
    .match(match_r24)
    );
LUT_5to1 U_r25(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r25),
    .second_2(rbve_out2_r25),
    .match(match_r25)
    );
LUT_5to1 U_r26(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r26),
    .second_2(rbve_out2_r26),
    .match(match_r26)
    );
LUT_5to1 U_r27(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r27),
    .second_2(rbve_out2_r27),
    .match(match_r27)
    );
LUT_5to1 U_r28(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r28),
    .second_2(rbve_out2_r28),
    .match(match_r28)
    );
LUT_5to1 U_r29(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r29),
    .second_2(rbve_out2_r29),
    .match(match_r29)
    );
LUT_5to1 U_r30(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r30),
    .second_2(rbve_out2_r30),
    .match(match_r30)
    );
LUT_5to1 U_r31(
    .clk(clk),
    .rst_n(rst_n),
    .lookup_en(lookup_en_ff3),
    .first_3(rbve_out1_r31),
    .second_2(rbve_out2_r31),
    .match(match_r31)
    );

//*********************
//MAIN CORE
//*********************

assign range_first = range[RANGE_L-1:RANGE_L-SUBR+8];// 2022.5.9, xym
// assign range_first = {1'b0,range[RANGE_L-1:RANGE_L-SUBR+8]};
assign range_second= range[RANGE_L-SUBR+7:RANGE_L-SUBR]; 
always@(posedge clk or negedge rst_n)
  begin
    if(~rst_n)
      begin
        mod_en1 <=0;
        mod_en2 <=0;
      end
    else if(odd && mod_en)
      begin
        mod_en1 <=0;
        mod_en2 <= 1;
      end 
    else if(!odd && mod_en) 
      begin
        mod_en1 <= 1;
        mod_en2 <= 0;
      end
    else 
      begin
        mod_en1 <= 0;
        mod_en2 <= 0;
      end
  end
always@(posedge clk or negedge rst_n)
  begin
    if(~rst_n)
    begin 
      addr_loc1 <= 0;
      cpu_data1 <= 0;
    end 
    else if(!odd) 
    begin 
      addr_loc1 <= addr_loc;
      cpu_data1 <= cpu_data[95:0];
    end
    else 
    begin 
      addr_loc1 <= 0;
      cpu_data1 <= 0;
    end
  end
always@(posedge clk or negedge rst_n)
  begin
    if(~rst_n)
    begin 
      addr_loc2 <= 0;
      cpu_data2 <= 0;
    end
    else if(odd)
    begin 
      addr_loc2 <= addr_loc;
      cpu_data2 <= cpu_data[63:0];
    end 
    else 
    begin 
      addr_loc2 <= 0;
      cpu_data2 <= 0;
    end 
  end
always@(posedge clk)
  begin
    if(~rst_n)
      begin
        lookup_en_ff1  <= 0;
        lookup_en_ff2  <= 0;
        lookup_en_ff3  <= 0;
        lookup_done    <= 0;  
      end
    else 
      begin 
        lookup_en_ff1  <= lookup_en;
        lookup_en_ff2  <= lookup_en_ff1;
        lookup_en_ff3  <= lookup_en_ff2;
        lookup_done    <= lookup_en_ff3;
      end 
  end
// always@(posedge clk or negedge rst_n)
//   begin
//     if(~rst_n)
//       begin
//         range_ff1 <= 0;
//         range_ff2 <= 0;
//         range_out <= 0;
//       end
//     else 
//       begin
//         range_ff1 <= range[RANGE_L-1-SUBR:0];
//         range_ff2 <= range_ff1;
//         range_out <= range_ff2;
//       end
//   end
always@(posedge clk or negedge rst_n)
  begin
    if(~rst_n)
      begin
        match_in_ff1 <= 0;
        match_in_ff2 <= 0;
        match_in_ff3 <= 0;
        match_in_ff4 <= 0;
      end
    else 
      begin
        match_in_ff1 <= match_in;
        match_in_ff2 <= match_in_ff1;
        match_in_ff3 <= match_in_ff2;
        match_in_ff4 <= match_in_ff3;
      end
  end
assign match_out=(lookup_done==1)?{match_r0,match_r1,match_r2,match_r3,match_r4,match_r5,match_r6,match_r7,match_r8,match_r9,
                  match_r10,match_r11,match_r12,match_r13,match_r14,match_r15,match_r16,match_r17,match_r18,match_r19,
                  match_r20,match_r21,match_r22,match_r23,match_r24,match_r25,match_r26,match_r27,match_r28,match_r29,
                  match_r30,match_r31
                 }& match_in_ff4:32'b0;
assign match_is = (match_out==0)?1'b0:1'b1;
//*********************
endmodule    // hookup byte controller block
    
